home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / gcc / ixemlsrc.lha / ixemul / ixnet / socket.c < prev    next >
C/C++ Source or Header  |  1996-03-13  |  18KB  |  767 lines

  1. /*
  2.  *  This file is part of ixnet.library for the Amiga.
  3.  *  Copyright (C) 1996 by Jeff Shepherd
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  $Id:$
  20.  *
  21.  *  $Log:$
  22.  *
  23.  */
  24.  
  25. #define KERNEL
  26. #include "ixnet.h"
  27.  
  28. #include <sys/socket.h>
  29. #include <sys/socketvar.h>
  30. #include <sys/ioctl.h>
  31. #include <net/if.h>
  32. #include <net/route.h>
  33. #include <netinet/in.h>
  34. #include <machine/param.h>
  35. #include <string.h>
  36. #include <inetd.h>
  37. #include <stdlib.h>
  38. #include "select.h"
  39. #include "ixprotos.h"
  40.  
  41. /* AS225 already has AF_UNIX sockets (sort of) but AmiTCP doesn't (shame on them :)) */
  42. /* #define USER_SOCKETS *//* include code for own AF_UNIX sockets */
  43. int _tcp_read    (struct file *fp, char *buf, int len);
  44. int _tcp_write    (struct file *fp, char *buf, int len);
  45. int _tcp_ioctl    (struct file *fp, int cmd, int inout, int arglen, caddr_t data);
  46. int _tcp_select (struct file *fp, int select_cmd, int io_mode);
  47. int _tcp_close    (struct file *fp);
  48.  
  49. #include "inet.h"
  50.  
  51. int
  52. _socket (int domain, int type, int protocol) {
  53.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  54.     register int network_protocol = p->u_networkprotocol;
  55.     int err = -1;
  56.  
  57.     switch (network_protocol) {
  58.     case IX_NETWORK_AS225:
  59.         err = SOCK_socket(p->u_SockBase, domain, type, protocol);
  60.     break;
  61.  
  62.     case IX_NETWORK_AMITCP:
  63.         err = TCP_Socket(p->u_TCPBase, domain, type, protocol);
  64.     break;
  65.     }
  66.     return err;
  67. }
  68.  
  69.  
  70. int
  71. _bind (struct file *fp, const struct sockaddr *name, int namelen) {
  72.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  73.     register int network_protocol = p->u_networkprotocol;
  74.     int error = -1;
  75.  
  76.     switch (network_protocol) {
  77.     case IX_NETWORK_AS225:
  78.         error = SOCK_bind(p->u_SockBase, fp->f_so, name, namelen);
  79.     break;
  80.  
  81.     case IX_NETWORK_AMITCP:
  82.         error = TCP_Bind(p->u_TCPBase, fp->f_so, name, namelen);
  83.     break;
  84.     }
  85.     return error;
  86. }
  87.  
  88. int
  89. _listen (struct file *fp, int backlog) {
  90.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  91.     register int network_protocol = p->u_networkprotocol;
  92.     int error = -1;
  93.  
  94.     switch (network_protocol) {
  95.     case IX_NETWORK_AS225:
  96.         error = SOCK_listen(p->u_SockBase, fp->f_so, backlog);
  97.     break;
  98.  
  99.     case IX_NETWORK_AMITCP:
  100.         error = TCP_Listen(p->u_TCPBase, fp->f_so, backlog);
  101.     break;
  102.     }
  103.     return error;
  104. }
  105.  
  106. int
  107. _accept (struct file *fp, struct sockaddr *name, int *namelen) {
  108.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  109.     register int network_protocol = p->u_networkprotocol;
  110.     int err = -1;
  111.     switch (network_protocol) {
  112.  
  113.     case IX_NETWORK_AS225:
  114.         err = SOCK_accept(p->u_SockBase,fp->f_so, name,namelen);
  115.     break;
  116.  
  117.     case IX_NETWORK_AMITCP:
  118.         err = TCP_Accept(p->u_TCPBase,fp->f_so, name, namelen);
  119.     break;
  120.     }
  121.     return err;
  122. }
  123.  
  124.  
  125. int
  126. _connect (struct file *fp, const struct sockaddr *name, int namelen) {
  127.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  128.     register int network_protocol = p->u_networkprotocol;
  129.     int error = -1;
  130.     switch (network_protocol) {
  131.     case IX_NETWORK_AS225:
  132.         error = SOCK_connect(p->u_SockBase,fp->f_so, name,namelen);
  133.     break;
  134.  
  135.     case IX_NETWORK_AMITCP:
  136.         error = TCP_Connect(p->u_TCPBase,fp->f_so, name,namelen);
  137.     break;
  138.     }
  139.     return error;
  140. }
  141.  
  142. int
  143. _sendto (struct file *fp, const void *buf, int len, int flags, const struct sockaddr *to, int tolen) {
  144.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  145.     register int network_protocol = p->u_networkprotocol;
  146.     int rc = -1;
  147.  
  148.     switch (network_protocol) {
  149.  
  150.     case IX_NETWORK_AS225:
  151.         rc = SOCK_sendto(p->u_SockBase,fp->f_so,buf,len,flags,to,tolen);
  152.     break;
  153.  
  154.     case IX_NETWORK_AMITCP:
  155.         rc = TCP_SendTo(p->u_TCPBase,fp->f_so,buf,len,flags,to,tolen);
  156.     break;
  157.     }
  158.  
  159.     return rc;
  160. }
  161.  
  162.  
  163. int
  164. _send (struct file *fp, const void *buf, int len, int flags) {
  165.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  166.     register int network_protocol = p->u_networkprotocol;
  167.     int rc = -1 ;
  168.  
  169.     switch (network_protocol) {
  170.  
  171.     case IX_NETWORK_AS225:
  172.         rc = SOCK_send(p->u_SockBase,fp->f_so,buf,len,flags);
  173.     break;
  174.  
  175.     case IX_NETWORK_AMITCP:
  176.         rc = TCP_Send(p->u_TCPBase,fp->f_so,buf,len,flags);
  177.     break;
  178.     }
  179.  
  180.     return rc;
  181. }
  182.  
  183.  
  184. int
  185. _sendmsg (struct file *fp, const struct msghdr *msg, int flags) {
  186.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  187.     register int network_protocol = p->u_networkprotocol;
  188.     int rc = -1;
  189.  
  190.     switch (network_protocol) {
  191.  
  192.     case IX_NETWORK_AS225:
  193.         rc = SOCK_sendmsg(p->u_SockBase,fp->f_so,msg,flags);
  194.     break;
  195.  
  196.     case IX_NETWORK_AMITCP:
  197.         rc = TCP_SendMsg(p->u_TCPBase,fp->f_so,msg,flags);
  198.     break;
  199.     }
  200.  
  201.     return rc;
  202. }
  203.  
  204.  
  205. int
  206. _recvfrom (struct file *fp, void *buf, int len, int flags, struct sockaddr *from, int *fromlen) {
  207.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  208.     register int network_protocol = p->u_networkprotocol;
  209.     int rc = -1;
  210.  
  211.     switch (network_protocol) {
  212.  
  213.     case IX_NETWORK_AS225:
  214.         rc = SOCK_recvfrom(p->u_SockBase,fp->f_so,buf,len,flags, from, fromlen);
  215.     break;
  216.  
  217.     case IX_NETWORK_AMITCP:
  218.         rc = TCP_RecvFrom(p->u_TCPBase,fp->f_so,buf,len,flags, from, fromlen);
  219.     break;
  220.     }
  221.  
  222.     return rc;
  223. }
  224.  
  225.  
  226. int
  227. _recv (struct file *fp, void *buf, int len, int flags) {
  228.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  229.     register int network_protocol = p->u_networkprotocol;
  230.     int rc = -1;
  231.  
  232.     switch (network_protocol) {
  233.  
  234.     case IX_NETWORK_AS225:
  235.         rc = SOCK_recv(p->u_SockBase,fp->f_so,buf,len,flags);
  236.     break;
  237.  
  238.     case IX_NETWORK_AMITCP:
  239.         rc = TCP_Recv(p->u_TCPBase,fp->f_so,buf,len,flags);
  240.     break;
  241.     }
  242.  
  243.     return rc;
  244. }
  245.  
  246.  
  247. int
  248. _recvmsg (struct file *fp, struct msghdr *msg, int flags) {
  249.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  250.     register int network_protocol = p->u_networkprotocol;
  251.     int rc = -1;
  252.  
  253.     switch (network_protocol) {
  254.  
  255.     case IX_NETWORK_AS225:
  256.         rc = SOCK_recvmsg(p->u_SockBase,fp->f_so,msg,flags);
  257.     break;
  258.  
  259.     case IX_NETWORK_AMITCP:
  260.         rc = TCP_RecvMsg(p->u_TCPBase,fp->f_so,msg,flags);
  261.     break;
  262.     }
  263.  
  264.     return rc;
  265. }
  266.  
  267. int _socketpair(int d, int type, int protocol, int sv[2]) {
  268.     errno = ENOSYS;
  269.     return -1;
  270. }
  271.  
  272. int
  273. _shutdown (struct file *fp, int how) {
  274.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  275.     register int network_protocol = p->u_networkprotocol;
  276.     int err = 0;
  277.  
  278.     switch (network_protocol) {
  279.  
  280.     case IX_NETWORK_AS225:
  281.         err = SOCK_shutdown(p->u_SockBase,fp->f_so,how);
  282.     break;
  283.  
  284.     case IX_NETWORK_AMITCP:
  285.         err = TCP_ShutDown(p->u_TCPBase,fp->f_so,how);
  286.     break;
  287.     }
  288.     return err;
  289. }
  290.  
  291.  
  292. int
  293. _setsockopt (struct file *fp, int level, int name, const void *val, int valsize) {
  294.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  295.     register int network_protocol = p->u_networkprotocol;
  296.     int err = 0;
  297.  
  298.     switch (network_protocol) {
  299.  
  300.     case IX_NETWORK_AS225:
  301.         err = SOCK_setsockopt(p->u_SockBase,fp->f_so,level,name,val, valsize);
  302.     break;
  303.  
  304.     case IX_NETWORK_AMITCP:
  305.         err = TCP_SetSockOpt(p->u_TCPBase,fp->f_so,level,name,val, valsize);
  306.     break;
  307.     }
  308.  
  309.     return err;
  310. }
  311.  
  312. int
  313. _getsockopt (struct file *fp, int level, int name, void *val, int *valsize) {
  314.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  315.     register int network_protocol = p->u_networkprotocol;
  316.     int err = 0;
  317.  
  318.     switch (network_protocol) {
  319.  
  320.     case IX_NETWORK_AS225:
  321.         err = SOCK_getsockopt(p->u_SockBase,fp->f_so,level,name,val, valsize);
  322.     break;
  323.  
  324.     case IX_NETWORK_AMITCP:
  325.         err = TCP_GetSockOpt(p->u_TCPBase,fp->f_so,level,name,val, valsize);
  326.     break;
  327.     }
  328.  
  329.     return err;
  330. }
  331.  
  332.  
  333. /*
  334.  * Get socket name.
  335.  */
  336. int
  337. _getsockname (struct file *fp, struct sockaddr *asa, int *alen) {
  338.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  339.     register int network_protocol = p->u_networkprotocol;
  340.     int err = -1;
  341.  
  342.     switch (network_protocol) {
  343.  
  344.     case IX_NETWORK_AS225:
  345.         err = SOCK_getsockname(p->u_SockBase,fp->f_so,asa,alen);
  346.     break;
  347.  
  348.     case IX_NETWORK_AMITCP:
  349.         err = TCP_GetSockName(p->u_TCPBase,fp->f_so,asa,alen);
  350.     break;
  351.     }
  352.  
  353.     return err;
  354. }
  355.  
  356. /*
  357.  * Get name of peer for connected socket.
  358.  */
  359. int
  360. _getpeername (struct file *fp, struct sockaddr *asa, int *alen) {
  361.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  362.     register int network_protocol = p->u_networkprotocol;
  363.     int err = -1;
  364.  
  365.     switch (network_protocol) {
  366.  
  367.     case IX_NETWORK_AS225:
  368.         err = SOCK_getpeername(p->u_SockBase,fp->f_so,asa,alen);
  369.     break;
  370.  
  371.     case IX_NETWORK_AMITCP:
  372.         err = TCP_GetPeerName(p->u_TCPBase,fp->f_so,asa,alen);
  373.     break;
  374.     }
  375.  
  376.     return err;
  377. }
  378.  
  379. int
  380. _tcp_read (struct file *fp, char *buf, int len) {
  381.     int ostat, rc;
  382.     struct user *p = &u;
  383.  
  384.     ostat = p->p_stat;
  385.     p->p_stat = SWAIT;
  386.  
  387.     rc = _recv(fp,buf,len, 0);
  388.  
  389.     if (CURSIG (p))
  390.     SetSignal (0, SIGBREAKF_CTRL_C);
  391.  
  392.     p->p_stat = ostat;
  393.  
  394.     if (errno == EINTR)
  395.     setrun (FindTask (0));
  396.  
  397.     return rc;
  398. }
  399.  
  400.  
  401. int
  402. _tcp_write (struct file *fp, char *buf, int len) {
  403.     struct user *p = &u;
  404.     int ostat, rc;
  405.  
  406.     ostat = p->p_stat;
  407.     p->p_stat = SWAIT;
  408.  
  409.     rc = _send(fp,buf,len,0);
  410.  
  411.     if (CURSIG (p))
  412.     SetSignal (0, SIGBREAKF_CTRL_C);
  413.  
  414.     p->p_stat = ostat;
  415.  
  416.     if (errno == EINTR)
  417.     setrun (FindTask (0));
  418.  
  419.     return rc;
  420. }
  421.  
  422. int
  423. _tcp_ioctl (struct file *fp, int cmd, int inout, int arglen, caddr_t data) {
  424.     register struct user *usr = &u;
  425.     register struct ixnet *p = (struct ixnet *)usr->u_ixnet;
  426.     register int network_protocol = p->u_networkprotocol;
  427.     int ostat, err = 0;
  428.  
  429.     ostat = usr->p_stat;
  430.     usr->p_stat = SWAIT;
  431.  
  432.     switch (network_protocol) {
  433.  
  434.     case IX_NETWORK_AS225:
  435.  
  436.         /* _SIGH_... they left almost everything neatly as it was in the BSD kernel
  437.          *    code they used, but for whatever reason they decided they needed their
  438.          *    own kind of ioctl encoding :-((
  439.          *
  440.          *    Well then, here we go, and map `normal' cmds into CBM cmds:
  441.          */
  442.  
  443.         switch (cmd) {
  444.         case SIOCADDRT         : cmd = ('r'<<8)|1; break;
  445.         case SIOCDELRT         : cmd = ('r'<<8)|2; break;
  446.         case SIOCSIFADDR     : cmd = ('i'<<8)|3; break;
  447.         case SIOCGIFADDR     : cmd = ('i'<<8)|4; break;
  448.         case SIOCSIFDSTADDR  : cmd = ('i'<<8)|5; break;
  449.         case SIOCGIFDSTADDR  : cmd = ('i'<<8)|6; break;
  450.         case SIOCSIFFLAGS    : cmd = ('i'<<8)|7; break;
  451.         case SIOCGIFFLAGS    : cmd = ('i'<<8)|8; break;
  452.         case SIOCGIFCONF     : cmd = ('i'<<8)|9; break;
  453.         case SIOCSIFMTU      : cmd = ('i'<<8)|10; break;
  454.         case SIOCGIFMTU      : cmd = ('i'<<8)|11; break;
  455.         case SIOCGIFBRDADDR  : cmd = ('i'<<8)|12; break;
  456.         case SIOCSIFBRDADDR  : cmd = ('i'<<8)|13; break;
  457.         case SIOCGIFNETMASK  : cmd = ('i'<<8)|14; break;
  458.         case SIOCSIFNETMASK  : cmd = ('i'<<8)|15; break;
  459.         case SIOCGIFMETRIC   : cmd = ('i'<<8)|16; break;
  460.         case SIOCSIFMETRIC   : cmd = ('i'<<8)|17; break;
  461.         case SIOCSARP         : cmd = ('i'<<8)|18; break;
  462.         case SIOCGARP         : cmd = ('i'<<8)|19; break;
  463.         case SIOCDARP         : cmd = ('i'<<8)|20; break;
  464.         case SIOCATMARK      : cmd = ('i'<<8)|21; break;
  465.         case FIONBIO         : cmd = ('m'<<8)|22; break;
  466.         case FIONREAD         : cmd = ('m'<<8)|23; break;
  467.         case FIOASYNC         : cmd = ('m'<<8)|24; break;
  468.         case SIOCSPGRP         : cmd = ('m'<<8)|25; break;
  469.         case SIOCGPGRP         : cmd = ('m'<<8)|26; break;
  470.  
  471.         default:
  472.         /* we really don't have to bother the library with cmds we can't even
  473.          * map over...
  474.          */
  475.         }
  476.         err = SOCK_ioctl(p->u_SockBase,fp->f_so,cmd,data);
  477.     break;
  478.  
  479.     case IX_NETWORK_AMITCP:
  480.         err = TCP_IoctlSocket(p->u_TCPBase,fp->f_so,cmd,data);
  481.     break;
  482.     }
  483.     if (CURSIG (usr))
  484.     SetSignal (0, SIGBREAKF_CTRL_C);
  485.  
  486.     usr->p_stat = ostat;
  487.  
  488.     if (errno == EINTR)
  489.     setrun (FindTask (0));
  490.  
  491.     return err;
  492. }
  493.  
  494. /* looks like ixemul.library can't grog ixnet.library calling ix_lock_base()
  495.  * moved most of this code back into ixemul.library
  496.  */
  497. int
  498. _tcp_close (struct file *fp) {
  499.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  500.     register int network_protocol = p->u_networkprotocol;
  501.     int err = 0;
  502.  
  503. #if 0
  504.     ix_lock_base ();
  505.     fp->f_count--;
  506.  
  507.     if (fp->f_count == 0) {
  508.     /* don't have the base locked for IN_close, this MAY block!! */
  509.     ix_unlock_base ();
  510. #endif
  511.     switch (network_protocol) {
  512.  
  513.         case IX_NETWORK_AS225:
  514.         err = SOCK_close (p->u_SockBase, fp->f_so);
  515.         break;
  516.  
  517.         case IX_NETWORK_AMITCP:
  518.         err = TCP_CloseSocket(p->u_TCPBase,fp->f_so);
  519.         break;
  520.     }
  521. #if 0
  522.     }
  523.     else
  524.     ix_unlock_base ();
  525. #endif
  526.     return err;
  527. }
  528.  
  529. int
  530. _tcp_select (struct file *fp, int select_cmd, int io_mode) {
  531.     int rc = -1;
  532.     fd_set in, out, exc;
  533.     struct timeval tv = {0,0};
  534.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  535.     register int network_protocol = p->u_networkprotocol;
  536.  
  537.     FD_ZERO(&in);
  538.     FD_ZERO(&out);
  539.     FD_ZERO(&exc);
  540.  
  541.     switch (io_mode) {
  542.     case SELMODE_IN:
  543.         FD_SET(fp->f_so,&in);
  544.     break;
  545.  
  546.     case SELMODE_OUT:
  547.         FD_SET(fp->f_so,&out);
  548.     break;
  549.  
  550.     case SELMODE_EXC:
  551.         FD_SET(fp->f_so,&exc);
  552.     break;
  553.     }
  554.  
  555.     switch (network_protocol) {
  556.     case IX_NETWORK_AS225:
  557.         rc = SOCK_selectwait(p->u_SockBase,fp->f_so+1,&in,&out,&exc,&tv,NULL);
  558.     break;
  559.  
  560.     case IX_NETWORK_AMITCP:
  561.         rc = TCP_WaitSelect(p->u_TCPBase,fp->f_so+1,&in,&out,&exc,&tv,NULL);
  562.     break;
  563.     }
  564.  
  565.     if (select_cmd == SELCMD_PREPARE)
  566.     return (1L << p->u_sigurg | 1L << p->u_sigio);
  567.  
  568.     return ((rc == 1) ? 1 : 0);
  569. }
  570.  
  571.  
  572. /*
  573.  *    init_inet_daemon.c - obtain socket accepted by the inetd
  574.  *
  575.  *    Copyright © 1994 AmiTCP/IP Group,
  576.  *             Network Solutions Development Inc.
  577.  *             All rights reserved.
  578.  *    Portions Copyright © 1995 by Jeff Shepherd
  579.  */
  580.  
  581. /* AS225 inet daemon stuff */
  582. struct inetmsg {
  583.     struct Message  msg;
  584.     ULONG   id;
  585. };
  586.  
  587. int
  588. init_inet_daemon(int *argc, char ***argv)
  589. {
  590.     register struct user *usr = &u;
  591.     register struct ixnet *p = (struct ixnet *)usr->u_ixnet;
  592.     struct file *fp;
  593.     register int network_protocol = p->u_networkprotocol;
  594.     int sock;
  595.  
  596.     if (network_protocol == IX_NETWORK_AS225) {
  597.     static int init_d(int *, char ***);
  598.     return init_d(argc,argv);
  599.     }
  600.     else if (network_protocol == IX_NETWORK_AMITCP) {
  601.     struct Process *me = (struct Process *)SysBase->ThisTask;
  602.     struct DaemonMessage *dm = (struct DaemonMessage *)me->pr_ExitData;
  603.     int fd,ostat;
  604.     int err;
  605.  
  606.     if (dm == NULL) {
  607.         /*
  608.         * No DaemonMessage, return error code - probably not an inet daemon
  609.         */
  610.         return -1;
  611.     }
  612.  
  613.     /*
  614.      * Obtain the server socket
  615.      */
  616.     sock = TCP_ObtainSocket(p->u_TCPBase,dm->dm_Id, dm->dm_Family, dm->dm_Type, 0);
  617.     if (sock < 0) {
  618.         /*
  619.         * If ObtainSocket fails we need to exit with this specific exit code
  620.         * so that the inetd knows to clean things up
  621.         */
  622.         exit(DERR_OBTAIN);
  623.     }
  624.  
  625.     ostat = usr->p_stat;
  626.     usr->p_stat = SWAIT;
  627.  
  628.     do {
  629.  
  630.         if ((err = falloc(&fp, &fd)))
  631.         break;
  632.  
  633.         fp->f_so = sock;
  634.         _set_socket_params(fp,AF_INET);
  635.     } while (0);
  636.  
  637.     if (CURSIG (usr))
  638.         SetSignal (0, SIGBREAKF_CTRL_C);
  639.  
  640.     usr->p_stat = ostat;
  641.  
  642.     if (err == EINTR)
  643.         setrun (FindTask (0));
  644.  
  645.     errno = err;
  646.     return err ? -1 : fd;
  647.     }
  648.     else
  649.     return -1;
  650. }
  651.  
  652. /* code loosely derived from timed.c from AS225r2 */
  653. /* this program was called from inetd if :
  654.  * 1> the first arg is a valid protocol(call getprotobyname)
  655.  * 2> inetd is started - FindPort("inetd") returns non-NULL
  656.  * NOT 3> argv[0] is the program found in inetd.conf for the program (scan inetd.conf)
  657.  */
  658. #include <netdb.h>
  659. #include <stdio.h>
  660. static int init_d(int *argc, char ***argv) {
  661.     struct user *usr = &u;
  662.     register struct ixnet *p = (struct ixnet *)usr->u_ixnet;
  663.     int ostat;
  664.     int err = 1;
  665.     int fd = -1;
  666.  
  667.     ostat = usr->p_stat;
  668.     usr->p_stat = SWAIT;
  669.  
  670.     /* save a little time with this comparison */
  671.     if (*argc >= 4) {
  672.     struct servent *serv, *serv2;
  673.     serv = SOCK_getservbyname(p->u_SockBase,(*argv)[1],"tcp");
  674.     serv2 = SOCK_getservbyname(p->u_SockBase,(*argv)[1],"udp");
  675.     if (serv || serv2) {
  676.         if (FindPort("inetd")) {
  677. #if 0 /* I think this isn't needed, SOCK_inherit should be enough */
  678.         char daemon[MAXPATHLEN];
  679.         char line[1024];
  680.         char protocol[MAXPATHLEN];
  681.         FILE *inetdconf;
  682.         int founddaemon = 0;
  683.         if (inetdconf = fopen("inet:db/inetd.conf","r")) {
  684.             while (!feof(inetdconf)) {
  685.             fgets(line,sizeof(line),inetdconf);
  686.             sscanf(line,"%s %*s %*s %*s %s",protocol,daemon);
  687.             if (!strcmp(protocol,(*argv)[1])) {
  688.                 founddaemon = 1;
  689.                 break;
  690.             }
  691.             }
  692.             fclose(inetdconf);
  693.  
  694.             if (founddaemon)  {
  695.             char *filename = FilePart(daemon);
  696. #endif
  697.             if (/*!stricmp((*argv)[0],filename)*/1) {
  698.                 struct file *fp;
  699.             long sock_arg;
  700.             int sock;
  701.                 int i;
  702.  
  703.                 sock_arg = atol((*argv)[2]);
  704.                 p->sock_id = atoi((*argv)[3]);
  705.                 sock = SOCK_inherit(p->u_SockBase,(void *)sock_arg);
  706.                 if (sock != -1) {
  707.                 p->u_daemon = 1; /* I was started from inetd */
  708.                 do {
  709.                     fd = 0;
  710.                     if ((err = falloc(&fp, &fd)))
  711.                     break;
  712.  
  713.                     fp->f_so = sock;
  714.                     _set_socket_params(fp,AF_INET);
  715.  
  716.                     /* get rid of the args that AS225 put in */
  717.                     for (i=1; i < (*argc)-3; i++) {
  718.                     (*argv)[i] = (*argv)[i+3];
  719.                     }
  720.                     (*argc) -= 3;
  721.                 } while (0);
  722.  
  723.                 if (CURSIG (usr))
  724.                     SetSignal (0, SIGBREAKF_CTRL_C);
  725.                 }
  726.             }
  727. #if 0
  728.             }
  729.         }
  730. #endif
  731.         }
  732.     }
  733.     }
  734.     usr->p_stat = ostat;
  735.     errno = err;
  736.     return err ? -1 : fd;
  737. }
  738.  
  739. /* This is only needed for AS225 */
  740. void shutdown_inet_daemon(void) {
  741.  
  742.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  743.     struct inetmsg inet_message;
  744.     struct MsgPort *msgport, *replyport;
  745.  
  746.     if (p->u_networkprotocol != IX_NETWORK_AS225 || !p->u_daemon)
  747.     return;
  748.  
  749.     if((inet_message.id = p->sock_id)) {
  750.     replyport = CreateMsgPort();
  751.     if(replyport) {
  752.         inet_message.msg.mn_Node.ln_Type = NT_MESSAGE;
  753.         inet_message.msg.mn_Length = sizeof(struct inetmsg);
  754.         inet_message.msg.mn_ReplyPort = replyport;
  755.  
  756.         msgport = FindPort("inetd");
  757.         if(msgport) {
  758.         PutMsg(msgport,(struct Message *)&inet_message);
  759.         /* we can't exit until we received a reply */
  760.         (void)WaitPort(replyport);
  761.         }
  762.         DeleteMsgPort(replyport);
  763.     }
  764.     }
  765. }
  766.  
  767.